#ifndef CONVERT_H
#define CONVERT_H

#include "esp_log.h"
#include <string>

extern "C" {
#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include "lua_cjson.h"
}

#define TAG "Convert"

class Convert {
public:
	Convert() {
		m_lua_state = luaL_newstate();
		if (m_lua_state) {
			luaL_openlibs(m_lua_state); // 加载标准库
			luaopen_cjson(m_lua_state); // 添加cjson
			lua_setglobal(m_lua_state, "cjson");
		} else {
			ESP_LOGE(TAG, "Failed to create Lua state");
		}
		ESP_LOGI(TAG, "init m_lua_state=%p", m_lua_state);
	}

	~Convert() {

		if (m_lua_state) {
			lua_close(m_lua_state);
			m_lua_state = nullptr;
		}
	}

	/**
	 * @param script_name Lua 脚本名字（调试/报错用）
	 * @param script_code Lua 脚本内容（必须包含一个 transform 函数）
	 * @param payload 传给 Lua 的参数（字符串/JSON）
	 * @param length payload 长度
	 * @return Lua 执行结果（字符串）
	 */
	char *lua_convert(const char *script_name,
					  const char *script_code,
					  const char *payload,
					  size_t length) {
		ESP_LOGI(TAG, "m_lua_state=%p", m_lua_state);
		if (!m_lua_state) {
			ESP_LOGE(TAG, "Lua state not initialized");
			return NULL;
		}

		// 加载并执行 Lua 脚本（必须定义 transform 函数）
		if (luaL_loadbuffer(m_lua_state, script_code, strlen(script_code), script_name) ||
			lua_pcall(m_lua_state, 0, 0, 0)) {
			ESP_LOGE(TAG, "Lua error: %s", lua_tostring(m_lua_state, -1));
			lua_pop(m_lua_state, 1);
			return NULL;
		}

		// 获取 transform 函数
		lua_getglobal(m_lua_state, "transform");
		if (!lua_isfunction(m_lua_state, -1)) {
			ESP_LOGE(TAG, "Lua script does not define 'transform' function");
			lua_pop(m_lua_state, 1);
			return NULL;
		}

		// 把 payload 作为参数传入
		lua_pushlstring(m_lua_state, payload, length);

		// 调用 transform(payload)，1 个参数，1 个返回值
		if (lua_pcall(m_lua_state, 1, 1, 0) != 0) {
			ESP_LOGE(TAG, "Lua runtime error: %s", lua_tostring(m_lua_state, -1));
			lua_pop(m_lua_state, 1);
			return NULL;
		}

		// 获取返回值
		const char *lua_result = NULL;
		char buf[32];

		if (lua_isstring(m_lua_state, -1)) {
			lua_result = lua_tostring(m_lua_state, -1);
		} else if (lua_isnumber(m_lua_state, -1)) {
			snprintf(buf, sizeof(buf), "%f", lua_tonumber(m_lua_state, -1));
			lua_result = buf;
		} else if (lua_isboolean(m_lua_state, -1)) {
			lua_result = lua_toboolean(m_lua_state, -1) ? "true" : "false";
		} else {
			lua_result = "";
		}

		// 复制到堆上，避免 lua_pop 后悬空
		char *result = (char *)malloc(strlen(lua_result) + 1);
		if (result) {
			strcpy(result, lua_result);
		}

		lua_pop(m_lua_state, 1); // 弹出 Lua 栈顶
		return result;			 // 调用者必须 free(result)
	}

private:
	lua_State *m_lua_state;
};

#endif // CONVERT_H
